﻿using System;
using System.Windows.Data;
using System.Windows.Media;

namespace Utils.Wpf.Converters
{
	public class MultiValueToColorConverter : IMultiValueConverter 
	{
		#region Attributes

		private static readonly Color _zeroColor;
		private static readonly Color _redColor;
		private static readonly Color _greenColor;

		#endregion

		#region Public Methods

		static MultiValueToColorConverter()
		{
			_zeroColor = Color.FromRgb(0xB8, 0xB8, 0xB8);
			_redColor = Color.FromRgb(0xFF, 0x00, 0x00);
			_greenColor = Color.FromRgb(0x7B, 0xE1, 0x00);
		}

		#endregion

		#region IMultiValueConverter Members

		// <summary>
		// Converts a value to a color between red - grey - green colors. The color corresponds to the value inside the scale -limit - 0 - +limit
		// </summary>
		// <param name="values">An array containing 3 fields: a decimal with the value, a decimal with the limit and a boolean to specify if the converter is enabled or not</param>
		public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
		{
			if (values != null && values.Length == 3 && (bool)values[2] && values[0] != null && values[0].ToString() != "{DependencyProperty.UnsetValue}")
			{
				decimal valueToConvert = Decimal.Parse(values[0].ToString());
				decimal maxValue;

				byte red;
				byte green;
				byte blue;

				if (valueToConvert >= 0)
				{
					maxValue = Decimal.Parse(values[1].ToString());

					red = valueToConvert < maxValue ? (byte)(_zeroColor.R + valueToConvert / maxValue * (_greenColor.R - _zeroColor.R)) : _greenColor.R;
					green = valueToConvert < maxValue ? (byte)(_zeroColor.G + valueToConvert / maxValue * (_greenColor.G - _zeroColor.G)) : _greenColor.G;
					blue = valueToConvert < maxValue ? (byte)(_zeroColor.B + valueToConvert / maxValue * (_greenColor.B - _zeroColor.B)) : _greenColor.B;
					return new SolidColorBrush(Color.FromRgb(red, green, blue));
				}
				else
				{
					maxValue = -Decimal.Parse(values[1].ToString());

					red = valueToConvert > maxValue ? (byte)(_zeroColor.R + valueToConvert / maxValue * (_redColor.R - _zeroColor.R)) : _redColor.R;
					green = valueToConvert > maxValue ? (byte)(_zeroColor.G + valueToConvert / maxValue * (_redColor.G - _zeroColor.G)) : _redColor.G;
					blue = valueToConvert > maxValue ? (byte)(_zeroColor.B + valueToConvert / maxValue * (_redColor.B - _zeroColor.B)) : _redColor.B;
					return new SolidColorBrush(Color.FromRgb(red, green, blue));
				}
			}
			else
			{
				return new SolidColorBrush(_zeroColor);
			}
		}

		public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
		{
			throw new NotImplementedException();
		}

		#endregion
	}
}
